package com.nova.pro.opengl.render;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;

import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * Created by Administrator on 2017-11-30.
 *
 * @author kzaxil
 * @since 1.1.0
 */
public class SquareRender implements Renderer {
    private final String vertexShaderCode =
            "attribute vec4 vPosition;    \n" +
                    "void main() {                \n" +
                    "    gl_Position = vPosition; \n" +
                    "}                            \n";

    private final String fragmentShaderCode =
            "precision mediump float;    \n" +
                    "uniform vec4 vColor;        \n" +
                    "void main() {               \n" +
                    "    gl_FragColor = vColor;  \n" +
                    "}                           \n";

    private float[] coords = {
            -0.5f, 0.5f, 0,     // left top
            -0.5f, -0.5f, 0,    // left bottom
            0.5f, -0.5f, 0,     // right bottom
            0.5f, 0.5f, 0       // right top
    };

    private short index[] = {0, 1, 2, 0, 2, 3};

    private int mProgram;
    private ShortBuffer indexBuffer;
    private FloatBuffer vertexBuffer;

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        ByteBuffer fb = ByteBuffer.allocateDirect(coords.length * 4);
        fb.order(ByteOrder.nativeOrder());
        vertexBuffer = fb.asFloatBuffer();
        vertexBuffer.put(coords);
        vertexBuffer.position(0);

        ByteBuffer sb = ByteBuffer.allocateDirect(index.length * 2);
        sb.order(ByteOrder.nativeOrder());
        indexBuffer = sb.asShortBuffer();
        indexBuffer.put(index);
        indexBuffer.position(0);

        int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);// 创建顶点着色器
        GLES20.glShaderSource(vertexShader, vertexShaderCode);// 将资源加入到顶点着色器
        GLES20.glCompileShader(vertexShader);// 编译顶点着色器

        int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        GLES20.glShaderSource(fragmentShader, fragmentShaderCode);
        GLES20.glCompileShader(fragmentShader);

        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram, vertexShader);
        GLES20.glAttachShader(mProgram, fragmentShader);
        GLES20.glLinkProgram(mProgram);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }

    /**
     * 关于{@link GLES20#glDrawElements(int, int, int, Buffer)}参数的解释
     * <ol>
     * <li>mode：指定绘制图元的类型</li>
     * <li>count：绘制图元的数量乘上一个图元的顶点数</li>
     * <li>type：索引值的类型，只能是下列值之一：GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT或GL_UNSIGNED_INT</li>
     * </ol>
     */
    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glUseProgram(mProgram);

        int vertexIndex = GLES20.glGetAttribLocation(mProgram, "vPosition");
        GLES20.glEnableVertexAttribArray(vertexIndex);
        GLES20.glVertexAttribPointer(vertexIndex, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);

        float color[] = {1.0f, 1.0f, 1.0f, 1.0f};
        GLES20.glUniform4fv(GLES20.glGetUniformLocation(mProgram, "vColor"), 1, color, 0);
//        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, coords.length / 3);// 顶点法绘制
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, index.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);// 索引法绘制

        GLES20.glDisableVertexAttribArray(vertexIndex);
    }
}
